<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>深入理解 HashMap 的哈希冲突处理机制</title>
    <link href="https://cdn.staticfile.org/font-awesome/6.4.0/css/all.min.css" rel="stylesheet">
    <link href="https://cdn.staticfile.org/tailwindcss/2.2.19/tailwind.min.css" rel="stylesheet">
    <link href="https://fonts.googleapis.com/css2?family=Noto+Serif+SC:wght@400;500;600;700&family=Noto+Sans+SC:wght@300;400;500;700&display=swap" rel="stylesheet">
    <script src="https://cdn.jsdelivr.net/npm/mermaid@latest/dist/mermaid.min.js"></script>
    <style>
        body {
            font-family: 'Noto Sans SC', Tahoma, Arial, Roboto, "Droid Sans", "Helvetica Neue", "Droid Sans Fallback", "Heiti SC", "Hiragino Sans GB", Simsun, sans-serif;
            background: linear-gradient(135deg, #f5f7fa 0%, #c3cfe2 100%);
            min-height: 100vh;
        }
        
        /* 首字下沉效果 */
        .drop-cap::first-letter {
            float: left;
            font-size: 4rem;
            line-height: 3rem;
            padding-right: 0.5rem;
            margin-top: 0.5rem;
            font-weight: 700;
            color: #4f46e5;
            font-family: 'Noto Serif SC', serif;
        }
        
        /* 代码块美化 */
        .code-block {
            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
            padding: 2px;
            border-radius: 12px;
            box-shadow: 0 10px 30px rgba(0, 0, 0, 0.2);
        }
        
        .code-content {
            background: #1e1e1e;
            border-radius: 10px;
            padding: 1.5rem;
            color: #d4d4d4;
            font-family: 'Consolas', 'Monaco', monospace;
            overflow-x: auto;
        }
        
        /* 卡片悬停效果 */
        .feature-card {
            transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
        }
        
        .feature-card:hover {
            transform: translateY(-5px);
            box-shadow: 0 20px 40px rgba(0, 0, 0, 0.15);
        }
        
        /* 标题装饰线 */
        .title-decoration {
            position: relative;
            display: inline-block;
        }
        
        .title-decoration::after {
            content: '';
            position: absolute;
            bottom: -10px;
            left: 0;
            width: 100%;
            height: 4px;
            background: linear-gradient(90deg, #4f46e5 0%, #7c3aed 100%);
            border-radius: 2px;
        }
        
        /* 引用样式 */
        .quote-box {
            position: relative;
            padding-left: 3rem;
        }
        
        .quote-box::before {
            content: '"';
            position: absolute;
            left: 0;
            top: -1rem;
            font-size: 4rem;
            color: #e0e7ff;
            font-family: 'Noto Serif SC', serif;
        }
        
        /* 数字标记 */
        .number-badge {
            display: inline-flex;
            align-items: center;
            justify-content: center;
            width: 2.5rem;
            height: 2.5rem;
            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
            color: white;
            border-radius: 50%;
            font-weight: 700;
            margin-right: 1rem;
            flex-shrink: 0;
        }
        
        /* 动画效果 */
        @keyframes fadeInUp {
            from {
                opacity: 0;
                transform: translateY(30px);
            }
            to {
                opacity: 1;
                transform: translateY(0);
            }
        }
        
        .animate-fadeInUp {
            animation: fadeInUp 0.8s ease-out;
        }
        
        /* Mermaid 图表样式 */
        .mermaid {
            display: flex;
            justify-content: center;
            margin: 2rem 0;
        }
    </style>
</head>
<body>
    <!-- Hero 区域 -->
    <section class="relative overflow-hidden">
        <div class="absolute inset-0 bg-gradient-to-br from-indigo-500 via-purple-500 to-pink-500 opacity-90"></div>
        <div class="relative container mx-auto px-6 py-24">
            <div class="text-center text-white animate-fadeInUp">
                <h1 class="text-5xl md:text-7xl font-bold mb-6">
                    <span class="title-decoration">HashMap 哈希冲突</span>
                </h1>
                <p class="text-xl md:text-2xl mb-8 opacity-90">深入探索 Java 集合框架的核心机制</p>
                <div class="flex justify-center space-x-4">
                    <span class="inline-flex items-center px-4 py-2 bg-white bg-opacity-20 rounded-full text-sm">
                        <i class="fas fa-code mr-2"></i> Java 核心技术
                    </span>
                    <span class="inline-flex items-center px-4 py-2 bg-white bg-opacity-20 rounded-full text-sm">
                        <i class="fas fa-database mr-2"></i> 数据结构
                    </span>
                    <span class="inline-flex items-center px-4 py-2 bg-white bg-opacity-20 rounded-full text-sm">
                        <i class="fas fa-chart-line mr-2"></i> 性能优化
                    </span>
                </div>
            </div>
        </div>
        <div class="absolute bottom-0 left-0 right-0">
            <svg viewBox="0 0 1440 120" fill="none" xmlns="http://www.w3.org/2000/svg">
                <path d="M0 120L60 110C120 100 240 80 360 70C480 60 600 60 720 65C840 70 960 80 1080 85C1200 90 1320 90 1380 90L1440 90V120H1380C1320 120 1200 120 1080 120C960 120 840 120 720 120C600 120 480 120 360 120C240 120 120 120 60 120H0V120Z" fill="white"/>
            </svg>
        </div>
    </section>

    <!-- 主要内容区域 -->
    <main class="container mx-auto px-6 py-12 max-w-6xl">
        <!-- 引言部分 -->
        <div class="bg-white rounded-2xl shadow-xl p-8 mb-12 animate-fadeInUp">
            <div class="quote-box">
                <p class="text-lg text-gray-700 leading-relaxed drop-cap">
                    在 Java 中，HashMap 是通过哈希值来确定键值对存储位置的。当两个对象的 <code class="px-2 py-1 bg-indigo-100 text-indigo-700 rounded">hashCode()</code> 返回值相等时，HashMap 会将它们存储在同一个桶（bucket）中，发生了哈希冲突（collision）。但即使 <code class="px-2 py-1 bg-indigo-100 text-indigo-700 rounded">hashCode</code> 相等，这两个对象也不一定是相等的。
                </p>
            </div>
        </div>

        <!-- 核心概念可视化 -->
        <div class="bg-white rounded-2xl shadow-xl p-8 mb-12">
            <h2 class="text-3xl font-bold text-gray-800 mb-6 flex items-center">
                <i class="fas fa-sitemap text-indigo-500 mr-3"></i>
                HashMap 工作原理概览
            </h2>
            <div class="mermaid">
                graph TD
                    A[键值对插入] --> B[计算 hashCode]
                    B --> C[计算桶位置]
                    C --> D{桶是否为空?}
                    D -->|是| E[直接插入]
                    D -->|否| F{发生哈希冲突}
                    F --> G[调用 equals 方法]
                    G --> H{键是否相等?}
                    H -->|是| I[更新值]
                    H -->|否| J{链表长度 > 8?}
                    J -->|是| K[转换为红黑树]
                    J -->|否| L[添加到链表]
                    K --> M[插入红黑树]
                    L --> N[完成]
                    M --> N
                    I --> N
                    E --> N
                    
                    style A fill:#e0e7ff,stroke:#6366f1,stroke-width:2px
                    style N fill:#d1fae5,stroke:#10b981,stroke-width:2px
                    style F fill:#fee2e2,stroke:#ef4444,stroke-width:2px
            </div>
        </div>

        <!-- 详细内容部分 -->
        <div class="grid grid-cols-1 lg:grid-cols-2 gap-8 mb-12">
            <!-- 计算哈希值和定位桶 -->
            <div class="feature-card bg-white rounded-2xl shadow-xl p-8">
                <div class="flex items-start mb-6">
                    <span class="number-badge">1</span>
                    <h3 class="text-2xl font-bold text-gray-800">计算哈希值和定位桶</h3>
                </div>
                <p class="text-gray-700 leading-relaxed mb-6">
                    当将键值对插入 HashMap 时，首先会根据键的 <code class="px-2 py-1 bg-indigo-100 text-indigo-700 rounded text-sm">hashCode()</code> 计算出一个哈希值。这个哈希值决定了键值对在哈希表中存储的桶位置。
                </p>
                <div class="code-block">
                    <div class="code-content">
                        <code>index = (n - 1) & hash</code>
                    </div>
                </div>
                <p class="text-gray-600 text-sm mt-4">
                    <i class="fas fa-info-circle text-indigo-500 mr-2"></i>
                    其中，<code class="px-1 py-0.5 bg-gray-100 text-gray-700 rounded text-sm">n</code> 是桶数组的长度，<code class="px-1 py-0.5 bg-gray-100 text-gray-700 rounded text-sm">hash</code> 是经过扰动函数计算后的哈希值。
                </p>
            </div>

            <!-- 处理哈希冲突 -->
            <div class="feature-card bg-white rounded-2xl shadow-xl p-8">
                <div class="flex items-start mb-6">
                    <span class="number-badge">2</span>
                    <h3 class="text-2xl font-bold text-gray-800">处理哈希冲突</h3>
                </div>
                <p class="text-gray-700 leading-relaxed mb-6">
                    当两个键的哈希值相等，且它们被映射到相同的桶位置时，就会发生哈希冲突。HashMap 使用以下方法来处理这种情况：
                </p>
                <div class="space-y-4">
                    <div class="flex items-start">
                        <i class="fas fa-link text-purple-500 mt-1 mr-3"></i>
                        <div>
                            <h4 class="font-semibold text-gray-800">链表结构</h4>
                            <p class="text-gray-600 text-sm">JDK 8 之前使用头插法，之后使用尾插法</p>
                        </div>
                    </div>
                    <div class="flex items-start">
                        <i class="fas fa-tree text-green-500 mt-1 mr-3"></i>
                        <div>
                            <h4 class="font-semibold text-gray-800">红黑树结构</h4>
                            <p class="text-gray-600 text-sm">链表长度超过 8 时自动转换，时间复杂度 O(log n)</p>
                        </div>
                    </div>
                </div>
            </div>
        </div>

        <!-- 比较对象的相等性 -->
        <div class="bg-gradient-to-r from-indigo-50 to-purple-50 rounded-2xl p-8 mb-12">
            <div class="flex items-start mb-6">
                <span class="number-badge">3</span>
                <h3 class="text-2xl font-bold text-gray-800">比较对象的相等性</h3>
            </div>
            <p class="text-gray-700 leading-relaxed mb-6">
                即使两个对象的 <code class="px-2 py-1 bg-white text-indigo-700 rounded">hashCode</code> 相等，HashMap 也不能直接认定它们是相同的对象。在插入新键值对时，HashMap 会遍历链表或红黑树结构，逐一使用 <code class="px-2 py-1 bg-white text-indigo-700 rounded">equals()</code> 方法比较新键和已存在键的相等性：
            </p>
            <div class="grid grid-cols-1 md:grid-cols-2 gap-6">
                <div class="bg-white rounded-xl p-6 shadow-lg">
                    <div class="flex items-center mb-3">
                        <i class="fas fa-check-circle text-green-500 text-2xl mr-3"></i>
                        <h4 class="font-bold text-gray-800">equals() 返回 true</h4>
                    </div>
                    <p class="text-gray-600">说明新键与已存在键是相同的对象，此时 HashMap 会认为这是一个重复的键，会更新